﻿// This software is the confidential and proprietary information of NetBay.
// Such confidential information should not be disclosed.
// NetBay copyright(c) 2012

#region

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Interactivity;
using GalaSoft.MvvmLight.Command;
using NetBay.Core.BusinessEntities;
using NetBay.Core.BusinessEntities.AdvancedSearchCriteria;
using NetBay.Core.BusinessEntities.Historic;
using NetBay.Core.Silverlight.Tools;
using Rio.Applications.Web.Services;
using Rio.Framework.Localisation;
using Rio.Framework.Pages.AppCode.Enums;
using Rio.Framework.Pages.AppCode.Models;
using Rio.Framework.Pages.Context;
using Rio.Framework.Pages.Controls.BaseClass;
using Rio.Framework.Pages.Manager;
using Rio.Framework.Pages.ModalControls;

#endregion

namespace Rio.Framework.Pages.Controls
{
    public partial class SearchPanel : IndexPanelBase
    {
        #region Delegates

        /// <summary>
        /// Delegate use to the event FolderIndexLoaded.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public delegate void FolderIndexEventHandler(object sender, EventArgs e);

        #endregion

        #region Readonly & Static Fields

        public static readonly DependencyProperty DocumentSearchResultProperty =
            DependencyProperty.Register("DocumentSearchResult", typeof (List<Document>), typeof (SearchPanel),
                                        new PropertyMetadata(OnDocumentSearchPropertyChanged));

        public static readonly DependencyProperty FolderSearchResultProperty =
            DependencyProperty.Register("FolderSearchResult", typeof (List<Folder>), typeof (SearchPanel),
                                        new PropertyMetadata(OnFolderSearchPropertyChanged));

        public static readonly DependencyProperty ListIndexProperty =
            DependencyProperty.Register("ListIndex", typeof (List<Index>), typeof (SearchPanel),
                                        new PropertyMetadata(OnListIndexPropertyChanged));

        #endregion

        #region Fields

        private SearchRequest _advancedFolderSearchRequest;
        private SearchPanelMode _currentSearchPanelMode = SearchPanelMode.Folder;
        private SearchRequest _documentSearchRequest;
        private SearchRequest _folderSearchRequest;
        private bool _isImportSearch;
        private string m_szFullTextHelper;
        private string m_szFullTextMsgMaxResultExceed;

        #endregion

        #region Constructors

        public SearchPanel()
        {
            InitializeComponent();

            if (!IsInDesignMode)
            {
                MinimizeControlToolbarCommand = new RelayCommand<bool>(MinimizeControlToolbar);
                SearchCommand = new RelayCommand(Search, CanExecuteSearch);
                ClearCriteriasCommand = new RelayCommand(ClearCriterias, CanExecuteClearCriterias);
                SaveSearchCommand = new RelayCommand(SaveSearch);

                AdvancedFolderSearchRequest = new SearchRequest();
                FolderSearchRequest = new SearchRequest();
                DocumentSearchRequest = new SearchRequest();

                InitLabel();

                LayoutRoot.KeyDown += LayoutRoot_KeyDown;
            }
        }

        #endregion

        #region Instance Properties

        public SearchRequest AdvancedFolderSearchRequest
        {
            get { return _advancedFolderSearchRequest; }
            set
            {
                _advancedFolderSearchRequest = value;
                OnPropertyChanged("AdvancedFolderSearchRequest");

                _advancedFolderSearchRequest.PropertyChanged +=
                    delegate { OnPropertyChanged("AdvancedFolderSearchRequest"); };
            }
        }

        public RelayCommand ClearCriteriasCommand { get; set; }

        public SearchPanelMode CurrentSearchPanelMode
        {
            get { return _currentSearchPanelMode; }
            set
            {
                _currentSearchPanelMode = value;
                OnPropertyChanged("CurrentSearchPanelMode");
            }
        }

        public SearchRequest DocumentSearchRequest
        {
            get { return _documentSearchRequest; }
            set
            {
                _documentSearchRequest = value;
                OnPropertyChanged("DocumentSearchRequest");

                _documentSearchRequest.PropertyChanged += delegate { OnPropertyChanged("DocumentSearchRequest"); };
            }
        }

        public List<Document> DocumentSearchResult
        {
            get { return (List<Document>) GetValue(DocumentSearchResultProperty); }
            set { SetValue(DocumentSearchResultProperty, value); }
        }

        public SearchRequest FolderSearchRequest
        {
            get { return _folderSearchRequest; }
            set
            {
                _folderSearchRequest = value;
                OnPropertyChanged("FolderSearchRequest");

                _folderSearchRequest.PropertyChanged += delegate { OnPropertyChanged("FolderSearchRequest"); };
            }
        }

        public List<Folder> FolderSearchResult
        {
            get { return (List<Folder>) GetValue(FolderSearchResultProperty); }
            set { SetValue(FolderSearchResultProperty, value); }
        }

        public List<string> IndexValues { get; set; }

        public bool IsImportSearch
        {
            get { return _isImportSearch; }
            set
            {
                _isImportSearch = value;
                OnPropertyChanged("IsImportSearch");
            }
        }

        public List<Index> ListIndex
        {
            get { return (List<Index>) GetValue(ListIndexProperty); }
            set { SetValue(ListIndexProperty, value); }
        }

        public RelayCommand<bool> MinimizeControlToolbarCommand { get; set; }
        public RelayCommand SaveSearchCommand { get; set; }
        public RelayCommand SearchCommand { get; set; }

        public new FolderType m_oCurrentFolderType
        {
            get { return base.m_oCurrentFolderType; }

            set
            {
                base.m_oCurrentFolderType = value;
                OnPropertyChanged("m_oCurrentFolderType");

                LoadAllModeIndex();
            }
        }

        public new Organization m_oCurrentOrganization
        {
            get { return base.m_oCurrentOrganization; }

            set
            {
                base.m_oCurrentOrganization = value;
                OnPropertyChanged("m_oCurrentOrganization");
            }
        }

        #endregion

        #region Instance Methods

        /// <summary>
        /// Translation
        /// </summary>
        public override void InitLabel()
        {
            m_sLblNoCriteria = Resx.GetLabel(ResxSearchPanel.MSG_NO_CRITERIA);
            m_oSplashscreen.Message = Resx.GetLabel(ResxCommon.SPLASHSCREEN_MESSAGE);
            m_szFullTextHelper = Resx.GetLabel(ResxSearchPanel.FULLTEXT_HELPER);
            m_szFullTextHelper = m_szFullTextHelper.Replace("\\n", "\n");
            m_szFullTextHelper = m_szFullTextHelper.Replace("\\t", "\t");
            m_szFullTextMsgMaxResultExceed = Resx.GetLabel(ResxSearchPanel.FULLTEXT_MAX_RESULT_EXCEED);

            foldersBarItem.Header = Resx.GetLabel(ResxSearchPanel.FOLDERINDEXSEARCH);
            foldersAndButton.Content = Resx.GetLabel(ResxCommon.AND);
            foldersOrButton.Content = Resx.GetLabel(ResxCommon.OR);
            foldersFullTextLabel.Text = Resx.GetLabel(ResxSearchPanel.CONTAINING);
            saveSearchCheckBox.Content = Resx.GetLabel(ResxSearchPanel.SAVE_SEARCH_CRITERIAS);

            advancedFoldersbarItem.Header = Resx.GetLabel(ResxSearchPanel.TAB_ADVANCED_SEARCH_LABEL);

            documentsBarItem.Header = Resx.GetLabel(ResxSearchPanel.DOCUMENTINDEXSEARCH);
            documentsAndButton.Content = Resx.GetLabel(ResxCommon.AND);
            documentsOrButton.Content = Resx.GetLabel(ResxCommon.OR);
            documentsFullTextLabel.Text = Resx.GetLabel(ResxSearchPanel.CONTAINING);

            clearButtonLabel.Text = Resx.GetLabel(ResxCommon.CLEAR);
            searchTextBlock.Text = Resx.GetLabel(ResxSearchPanel.SEARCH);
        }

        /// <summary>
        /// Called when [get documents query callback].
        /// </summary>
        /// <param name="result">The result.</param>
        public void OnGetDocumentsQueryCallback(LoadOperation<Document> result)
        {
            DocumentSearchResult = new List<Document>(result.Entities);
            SplashScreenClose();
        }

        /// <summary>
        /// Search folder query callback
        /// </summary>
        /// <param name="result"></param>
        public void OnGetFoldersQueryCallback(LoadOperation<Folder> result)
        {
            FolderSearchResult = new List<Folder>(result.Entities);

            if (CurrentSearchPanelMode == SearchPanelMode.Folder)
            {
                FolderSearchRequest.SaveSearch = false;
                FolderSearchRequest.EnableSaveSearch = true;

                AddHistoricSearch();
            }

            SplashScreenClose();
        }

        /// <summary>
        /// Performs the search by a request in URI.
        /// </summary>
        public void PerformSearchByUri()
        {
            //Find Organization
            CurrentSearchPanelMode = SearchPanelMode.Folder;

            //Listen the change of ItemsSource of FolderType ListBox
            UCOrganizationType.FolderTypeSourceChanged += PerformSearchByUriFolderTypeSourceChanged;

            //Set Organization
            m_oCurrentOrganization =
                UCOrganizationType.Organizations.Where(
                    o => o.Identifier == QueryByUriManager.SearchInstance.OrganizationId).FirstOrDefault();
        }

        /// <summary>
        /// Perform search switch
        /// </summary>
        public void Search()
        {
            MessageBoxChildWindow L_oCriteriaMessage = new MessageBoxChildWindow(
                String.Empty,
                m_sLblNoCriteria,
                MessageBoxButtons.Ok,
                MessageBoxIcon.Warning);

            switch (CurrentSearchPanelMode)
            {
                case SearchPanelMode.Folder:
                    FolderSearchRequest.Criterias = foldersIndex.GetIndexIdValues();
                    if (FolderSearchRequest.IsSearchRequestValid(false))
                    {
                        m_oSplashscreen.Show();
                        ModalDialogController.Launch(m_oSplashscreen);

                        if (String.IsNullOrWhiteSpace(FolderSearchRequest.FullTextSearch))
                        {
                            FolderSearch(FolderSearchRequest.Criterias);
                        }
                        else
                        {
                            FolderSearchWithFullText(FolderSearchRequest.Criterias);
                        }
                    }
                    else
                    {
                        L_oCriteriaMessage.ShowDialog();

                        FolderSearchRequest.SaveSearch = false;
                        FolderSearchRequest.EnableSaveSearch = false;
                    }
                    break;
                case SearchPanelMode.AdvancedFolder:
                    AdvancedFolderSearchRequest.AdvancedCriterias = advancedSearchIndex.GetAllValues();
                    if (AdvancedFolderSearchRequest.IsSearchRequestValid(true))
                    {
                        m_oSplashscreen.Show();
                        ModalDialogController.Launch(m_oSplashscreen);
                        PerformAdvancedSearch(AdvancedFolderSearchRequest.AdvancedCriterias);
                    }
                    else
                    {
                        L_oCriteriaMessage.ShowDialog();
                    }
                    break;
                case SearchPanelMode.Document:
                    DocumentSearchRequest.Criterias = documentsIndex.GetIndexIdValues();
                    if (DocumentSearchRequest.IsSearchRequestValid(false))
                    {
                        m_oSplashscreen.Show();
                        ModalDialogController.Launch(m_oSplashscreen);

                        if (String.IsNullOrWhiteSpace(DocumentSearchRequest.FullTextSearch))
                        {
                            DocumentSearch(DocumentSearchRequest.Criterias);
                        }
                        else
                        {
                            DocumentSearchWithFullText(DocumentSearchRequest.Criterias);
                        }
                    }
                    else
                    {
                        L_oCriteriaMessage.ShowDialog();
                    }
                    break;
            }

            m_oFolderType = m_oCurrentFolderType;
            m_oOrganization = m_oCurrentOrganization;
        }

        /// <summary>
        /// Called when [clear criterias processed].
        /// </summary>
        protected void OnClearCriteriasProcessed()
        {
            if (ClearCriteriasProcessed != null)
            {
                ClearCriteriasProcessed(this, new EventArgs());
            }
        }

        protected void OnDocumentSearchPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            if (DocumentSearchPropertyChanged != null)
            {
                DocumentSearchPropertyChanged(this, e);
            }

            return;
        }

        protected void OnFolderSearchPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            if (FolderSearchPropertyChanged != null)
            {
                FolderSearchPropertyChanged(this, e);
            }

            return;
        }

        protected void OnListIndexPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            if (ListIndexPropertyChanged != null)
            {
                ListIndexPropertyChanged(this, e);
            }
            return;
        }

        /// <summary>
        /// Adds the historic search.
        /// </summary>
        private void AddHistoricSearch(bool isUserSaving = false)
        {
            //Create list of IndexValue + IndexId + IndexLabel
            List<HistoricIndex> historicIndexList = foldersIndex.GetListIndexForHistorical();

            //Seralize list
            string historicIndexListSerialized = SerializationHelper.Serialize(historicIndexList);

            BusinessEntitiesDomainContext businessEntitiesDomainContext = new BusinessEntitiesDomainContext();
            var query = businessEntitiesDomainContext.AddHistoricInfoConsultQuery(
                (int) Constant.UserActions.RECHERCHE,
                m_oCurrentFolderType.Identifier,
                0,
                null,
                null,
                null,
                historicIndexListSerialized,
                isUserSaving,
                0,
                FolderSearchResult.Count,
                0,
                null);

            businessEntitiesDomainContext.Load(query);
        }

        /// <summary>
        /// Determines whether this instance [can execute clear criterias].
        /// </summary>
        /// <returns>
        ///   <c>true</c> if this instance [can execute clear criterias]; otherwise, <c>false</c>.
        /// </returns>
        private bool CanExecuteClearCriterias()
        {
            if (m_oCurrentOrganization == null)
                return false;

            if (m_oCurrentFolderType == null)
                return false;

            return true;
        }

        /// <summary>
        /// Determines whether this instance [can execute search].
        /// </summary>
        /// <returns>
        ///   <c>true</c> if this instance [can execute search]; otherwise, <c>false</c>.
        /// </returns>
        private bool CanExecuteSearch()
        {
            if (m_oCurrentOrganization == null)
                return false;

            if (m_oCurrentFolderType == null)
                return false;

            return true;
        }

        /// <summary>
        /// Clear current state element
        /// </summary>
        private void ClearCriterias()
        {
            switch (CurrentSearchPanelMode)
            {
                case SearchPanelMode.Folder:
                    if (foldersIndex != null) foldersIndex.ClearCriterias();
                    if (FolderSearchRequest != null)
                    {
                        if (FolderSearchRequest.Criterias != null) FolderSearchRequest.Criterias.Clear();
                        FolderSearchRequest.EnableSaveSearch = false;
                        FolderSearchRequest.FullTextSearch = String.Empty;
                        FolderSearchRequest.SaveSearch = false;
                        FolderSearchRequest.UseAndOperator = true;
                    }
                    break;
                case SearchPanelMode.AdvancedFolder:
                    if (advancedSearchIndex != null) advancedSearchIndex.ClearCriterias();
                    if (AdvancedFolderSearchRequest != null)
                    {
                        if (AdvancedFolderSearchRequest.AdvancedCriterias != null)
                            AdvancedFolderSearchRequest.AdvancedCriterias.Clear();
                        AdvancedFolderSearchRequest.EnableSaveSearch = false;
                        AdvancedFolderSearchRequest.FullTextSearch = String.Empty;
                        AdvancedFolderSearchRequest.SaveSearch = false;
                        AdvancedFolderSearchRequest.UseAndOperator = true;
                    }
                    break;
                case SearchPanelMode.Document:

                    if (documentsIndex != null) documentsIndex.ClearCriterias();
                    if (DocumentSearchRequest != null)
                    {
                        if (DocumentSearchRequest.Criterias != null) DocumentSearchRequest.Criterias.Clear();
                        DocumentSearchRequest.EnableSaveSearch = false;
                        DocumentSearchRequest.FullTextSearch = String.Empty;
                        DocumentSearchRequest.SaveSearch = false;
                        DocumentSearchRequest.UseAndOperator = true;
                    }
                    break;
            }

            OnClearCriteriasProcessed();
        }

        /// <summary>
        /// Search Document
        /// </summary>
        private void DocumentSearch(Dictionary<long, string> p_oDocumentCriteriaFilter)
        {
            if ((m_oCurrentOrganization != null) && (m_oCurrentFolderType != null))
            {
                string L_szOriginFilename;
                p_oDocumentCriteriaFilter.TryGetValue((int) DocumentSearchIdControl.OriginFilename,
                                                      out L_szOriginFilename);
                string L_szNote;
                p_oDocumentCriteriaFilter.TryGetValue((int) DocumentSearchIdControl.Note, out L_szNote);
                string L_szAuthor;
                p_oDocumentCriteriaFilter.TryGetValue((int) DocumentSearchIdControl.Author, out L_szAuthor);
                string L_szChronoNumber;
                p_oDocumentCriteriaFilter.TryGetValue((int) DocumentSearchIdControl.ChronoNumber, out L_szChronoNumber);

                L_szNote = L_szNote ?? String.Empty;
                L_szChronoNumber = L_szChronoNumber ?? String.Empty;

                var query = GetDataContext.SearchDocumentsQuery(
                    m_oCurrentOrganization.Identifier,
                    m_oCurrentFolderType.Identifier,
                    L_szNote,
                    L_szChronoNumber,
                    L_szAuthor,
                    L_szOriginFilename,
                    true);
                GetDataContext.Load(query, OnGetDocumentsQueryCallback, null);
            }
        }

        /// <summary>
        /// This method search documents combining fultext search and document search (AND/OR)
        /// </summary>
        private void DocumentSearchWithFullText(Dictionary<long, string> p_oDocumentCriteriaFilter)
        {
            if ((m_oCurrentOrganization != null) && (m_oCurrentFolderType != null))
            {
                string L_szOriginFilename;
                p_oDocumentCriteriaFilter.TryGetValue((int) DocumentSearchIdControl.OriginFilename,
                                                      out L_szOriginFilename);
                string L_szNote;
                p_oDocumentCriteriaFilter.TryGetValue((int) DocumentSearchIdControl.Note, out L_szNote);
                string L_szAuthor;
                p_oDocumentCriteriaFilter.TryGetValue((int) DocumentSearchIdControl.Author, out L_szAuthor);
                string L_szChronoNumber;
                p_oDocumentCriteriaFilter.TryGetValue((int) DocumentSearchIdControl.ChronoNumber, out L_szChronoNumber);

                L_szNote = L_szNote ?? String.Empty;
                L_szChronoNumber = L_szChronoNumber ?? String.Empty;

                GetDataContext.GetFullTextMaxResultControl(
                    DocumentSearchRequest.FullTextSearch,
                    GlobalWebContext.Culture, delegate(InvokeOperation<bool> result)
                                                  {
                                                      if (result.Value)
                                                      {
                                                          var query =
                                                              GetDataContext.SearchDocumentsWithFullSearchQuery(
                                                                  m_oCurrentOrganization.Identifier,
                                                                  m_oCurrentFolderType.Identifier,
                                                                  DocumentSearchRequest.UseAndOperator ? "AND" : "OR",
                                                                  DocumentSearchRequest.FullTextSearch,
                                                                  GlobalWebContext.Culture,
                                                                  L_szNote,
                                                                  L_szChronoNumber,
                                                                  L_szAuthor,
                                                                  L_szOriginFilename
                                                                  );
                                                          GetDataContext.Load(query, OnGetDocumentsQueryCallback, null);
                                                      }
                                                      else
                                                      {
                                                          SplashScreenClose();
                                                          MessageBoxChildWindow L_oMessage =
                                                              new MessageBoxChildWindow("FullText",
                                                                                        m_szFullTextMsgMaxResultExceed,
                                                                                        MessageBoxButtons.Ok,
                                                                                        MessageBoxIcon.Information);
                                                          L_oMessage.ShowDialog();
                                                      }
                                                  },
                    null);
            }
        }

        /// <summary>
        /// Search folder
        /// </summary>
        private void FolderSearch(Dictionary<long, string> p_oCriteriaFilter)
        {
            if ((m_oCurrentOrganization != null) && (m_oCurrentFolderType != null))
            {
                var query = GetDataContext.GetFoldersQuery(m_oCurrentOrganization.Identifier,
                                                           m_oCurrentFolderType.Identifier,
                                                           p_oCriteriaFilter);

                GetDataContext.Load(query, OnGetFoldersQueryCallback, null);
            }
        }

        /// <summary>
        /// This method search folders combining fultext search and folder search (AND/OR)
        /// </summary>
        private void FolderSearchWithFullText(Dictionary<long, string> p_oCriteriaFilter)
        {
            if ((m_oCurrentOrganization != null) && (m_oCurrentFolderType != null))
            {
                string fullTextSearch = null;

                switch (CurrentSearchPanelMode)
                {
                    case SearchPanelMode.Folder:
                        fullTextSearch = FolderSearchRequest.FullTextSearch;
                        break;
                    case SearchPanelMode.AdvancedFolder:
                        fullTextSearch = AdvancedFolderSearchRequest.FullTextSearch;
                        break;
                    case SearchPanelMode.Document:
                        fullTextSearch = DocumentSearchRequest.FullTextSearch;
                        break;
                }

                GetDataContext.GetFullTextMaxResultControl(
                    fullTextSearch,
                    GlobalWebContext.Culture,
                    delegate(InvokeOperation<bool> result)
                        {
                            if (result.Value)
                            {
                                bool useAndOperator = true;

                                switch (CurrentSearchPanelMode)
                                {
                                    case SearchPanelMode.Folder:
                                        useAndOperator = FolderSearchRequest.UseAndOperator;
                                        break;
                                    case SearchPanelMode.AdvancedFolder:
                                        useAndOperator = AdvancedFolderSearchRequest.UseAndOperator;
                                        break;
                                    case SearchPanelMode.Document:
                                        useAndOperator = DocumentSearchRequest.UseAndOperator;
                                        break;
                                }

                                var query =
                                    GetDataContext.GetFoldersWithFullSearchQuery(m_oCurrentOrganization.Identifier,
                                                                                 m_oCurrentFolderType.Identifier,
                                                                                 useAndOperator ? "AND" : "OR",
                                                                                 fullTextSearch,
                                                                                 GlobalWebContext.Culture,
                                                                                 p_oCriteriaFilter);


                                GetDataContext.Load(query, OnGetFoldersQueryCallback, null);
                            }
                            else
                            {
                                SplashScreenClose();
                                MessageBoxChildWindow L_oMessage = new MessageBoxChildWindow("FullText",
                                                                                             m_szFullTextMsgMaxResultExceed,
                                                                                             MessageBoxButtons.Ok,
                                                                                             MessageBoxIcon.Information);
                                L_oMessage.ShowDialog();
                            }
                        },
                    null);
            }
        }

        /// <summary>
        /// Init advanced search control
        /// </summary>
        private void LoadAdvancedSearchModeIndex()
        {
            advancedSearchIndex.Initialize(m_oCurrentOrganization, m_oCurrentFolderType);
        }

        /// <summary>
        /// Loads the index of all mode.
        /// </summary>
        private void LoadAllModeIndex()
        {
            if (m_oCurrentFolderType != null)
            {
                ListIndex = new List<Index>(m_oCurrentFolderType.LstIndex);

                foldersIndex.Clear();
                LoadFolderSearchModeIndex();

                advancedSearchIndex.Clear();
                LoadAdvancedSearchModeIndex();

                documentsIndex.Clear();
                LoadDocumentSearchModeIndex();
            }

            UpdateCommands();
        }

        /// <summary>
        /// Add index criteria control with help assistance values (with filter and without filter)
        /// </summary>
        private void LoadDocumentSearchModeIndex()
        {
            List<Index> documentIndex = new List<Index>();

            //OriginFilename
            Index OriginFilename = new Index
                                       {
                                           Type = (int) IndexDomainServiceEnums.IndexType.String,
                                           Indentifier = (int) DocumentSearchIdControl.OriginFilename,
                                           IndexLabel = Resx.GetLabel(ResxInfosDocument.ORIGIN_FILE),
                                           IsVisible = true
                                       };
            documentIndex.Add(OriginFilename);

            //Author
            Index Author = new Index
            {
                Type = (int)IndexDomainServiceEnums.IndexType.String,
                Indentifier = (int)DocumentSearchIdControl.Author,
                IndexLabel = Resx.GetLabel(ResxInfosDocument.AUTHOR),
                IsVisible = true
            };
            documentIndex.Add(Author);

            //ChronoNumber
            Index PhotoCredit = new Index
            {
                Type = (int)IndexDomainServiceEnums.IndexType.String,
                Indentifier = (int)DocumentSearchIdControl.ChronoNumber,
                IndexLabel = Resx.GetLabel(ResxInfosDocument.PHOTO_CREDIT),
                IsVisible = true
            };
            documentIndex.Add(PhotoCredit);

            //Note
            Index Note = new Index
                             {
                                 Type = (int) IndexDomainServiceEnums.IndexType.String,
                                 Indentifier = (int) DocumentSearchIdControl.Note,
                                 IndexLabel = Resx.GetLabel(ResxInfosDocument.NOTE),
                                 IsVisible = true
                             };
            documentIndex.Add(Note);




            documentsIndex.InitializeControlWithIndex(m_oCurrentOrganization, m_oCurrentFolderType, documentIndex);
            documentsIndex.HideFilters();

            UpdateCommands();
        }

        /// <summary>
        /// Add index criteria control with help assistance values (with filter and without filter)
        /// </summary>
        private void LoadFolderSearchModeIndex()
        {
            if (IndexValues != null && IndexValues.Count > 0)
                foldersIndex.InitializeControl(m_oCurrentOrganization, m_oCurrentFolderType, IndexValues);
            else
                foldersIndex.InitializeControl(m_oCurrentOrganization, m_oCurrentFolderType);

            UpdateCommands();

            //Launch the event to notify that all indexes are loaded in StackPanel (it used in case of a search bu uri)
            if (FolderIndexLoaded != null)
            {
                FolderIndexLoaded(this, new EventArgs());
            }
        }

        /// <summary>
        /// Minimizes the control toolbar.
        /// </summary>
        /// <param name="minimizeToolbar">if set to <c>true</c> [minimize toolbar].</param>
        private void MinimizeControlToolbar(bool minimizeToolbar)
        {
            if (minimizeToolbar)
                VisualStateManager.GoToState(this, "Minimized", false);
            else
                VisualStateManager.GoToState(this, "Default", false);
        }

        /// <summary>
        /// Perform an advanced search query
        /// </summary>
        /// <param name="p_oCriteriaFilter">Search criterias</param>
        private void PerformAdvancedSearch(List<AdvancedSearchCriteriaItem> p_oCriteriaFilter)
        {
            if ((m_oCurrentOrganization != null) && (m_oCurrentFolderType != null))
            {
                //Serialization data
                string sData = SerializationHelper.Serialize(p_oCriteriaFilter);
                var query = GetDataContext.GetFoldersForAdvancedSearchQuery(
                    sData,
                    m_oCurrentOrganization.Identifier,
                    m_oCurrentFolderType.Identifier
                    );

                GetDataContext.Load(query, OnGetFoldersQueryCallback, null);
            }
        }

        /// <summary>
        /// Saves the search.
        /// </summary>
        private void SaveSearch()
        {
            //Insure there is at least one criteria
            bool isValid = false;

            FolderSearchRequest.Criterias = foldersIndex.GetIndexIdValues();

            if (FolderSearchRequest.IsSearchRequestValid(false))
            {
                isValid = true;
            }

            if (isValid)
            {
                AddHistoricSearch(true);
            }
            else
            {
                MessageBoxChildWindow L_oCriteriaMessage = new MessageBoxChildWindow(String.Empty, m_sLblNoCriteria,
                                                                                     MessageBoxButtons.Ok,
                                                                                     MessageBoxIcon.Warning);
                L_oCriteriaMessage.ShowDialog();

                FolderSearchRequest.EnableSaveSearch = false;
                FolderSearchRequest.SaveSearch = false;
            }
        }

        /// <summary>
        /// Close SplashScreen
        /// </summary>
        private void SplashScreenClose()
        {
            ModalDialogController.Close();
            m_oSplashscreen.Close();
        }

        /// <summary>
        /// Updates the commands.
        /// </summary>
        private void UpdateCommands()
        {
            SearchCommand.RaiseCanExecuteChanged();
            ClearCriteriasCommand.RaiseCanExecuteChanged();
        }

        #endregion

        #region Event Handling

        /// <summary>
        /// Handles the Click event of the ButtonFullTextHelper control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void ButtonFullTextHelperClick(object sender, RoutedEventArgs e)
        {
            MessageBoxChildWindow L_oMessage = new MessageBoxChildWindow("FullText", m_szFullTextHelper,
                                                                         MessageBoxButtons.Ok,
                                                                         MessageBoxIcon.Information);
            L_oMessage.ShowDialog();
        }

        /// <summary>
        /// run indexing with enter key
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LayoutRoot_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter && SearchCommand.CanExecute(null))
            {
                Search();
            }
        }

        /// <summary>
        /// Performs the search by URI folder index loaded.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void PerformSearchByUriFolderIndexLoaded(object sender, EventArgs e)
        {
            FolderIndexLoaded -= PerformSearchByUriFolderIndexLoaded;

            //Set Index value for each control
            foreach (KeyValuePair<int, string> item in QueryByUriManager.SearchInstance.IndexArgs)
                foldersIndex[item.Key - 1] = item.Value;

            QueryByUriManager.Finish();

            Search();
        }

        /// <summary>
        /// Performs the search by URI folder type source changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void PerformSearchByUriFolderTypeSourceChanged(object sender, EventArgs e)
        {
            UCOrganizationType.FolderTypeSourceChanged -= PerformSearchByUriFolderTypeSourceChanged;

            //Attach to this event to be sure that all indexes are loaded to fill its with query string
            FolderIndexLoaded += PerformSearchByUriFolderIndexLoaded;

            //Set FolderType
            m_oCurrentFolderType =
                UCOrganizationType.FolderTypes.Where(f => f.Identifier == QueryByUriManager.SearchInstance.FolderTypeId)
                    .FirstOrDefault();
        }

        /// <summary>
        /// Handles the Loaded event of the UCSearchPanel control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void UCSearchPanel_Loaded(object sender, RoutedEventArgs e)
        {
            if (CurrentUser.CTX_DefaultOrganization > 0)
            {
                foreach (
                    Organization org in
                        CurrentUser.GroupList.SelectMany(
                            g =>
                            g.OrganizationList.Where(org => org.Identifier == CurrentUser.CTX_DefaultOrganization)))
                {
                    m_oCurrentOrganization = org;
                }
            }

            if (CurrentUser.CTX_DefaultType > 0)
            {
                foreach (FolderType FolderTypeInOrga in m_oCurrentOrganization.FolderTypesList.Where(FolderTypeInOrga => FolderTypeInOrga.Identifier == CurrentUser.CTX_DefaultType))
                {
                    m_oCurrentFolderType = FolderTypeInOrga;
                }
            }
        }

        #endregion

        #region Event Declarations

        public event EventHandler ClearCriteriasProcessed;
        public event DependencyPropertyChangedEventHandler DocumentSearchPropertyChanged;

        /// <summary>
        /// Event fired when all indexes are loaded in StackPanel (in Folder Search).
        /// This is useful when a search bu uri.
        /// </summary>
        public event FolderIndexEventHandler FolderIndexLoaded;

        public event DependencyPropertyChangedEventHandler FolderSearchPropertyChanged;
        public event DependencyPropertyChangedEventHandler ListIndexPropertyChanged;

        #endregion

        #region Class Methods

        private static void OnDocumentSearchPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            ((SearchPanel) obj).OnDocumentSearchPropertyChanged(e);
        }

        private static void OnFolderSearchPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            ((SearchPanel) obj).OnFolderSearchPropertyChanged(e);
        }

        private static void OnListIndexPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            ((SearchPanel) obj).OnListIndexPropertyChanged(e);
        }

        #endregion
    }

    public class LoadUcOrganizationTypePanelBehavior : Behavior<UCOrganizationTypePanel>
    {
        #region Instance Methods

        protected override void OnAttached()
        {
            base.OnAttached();

            AssociatedObject.InitControl(AppDisplayMode.Search);
        }

        #endregion
    }

    internal enum DocumentSearchIdControl
    {
        OriginFilename = 0,
        Note = 1,
        Author = 2,
        ChronoNumber = 3
    }

    /// <summary>
    /// Search State
    /// </summary>
    public enum SearchPanelMode
    {
        Folder = 0,
        AdvancedFolder = 1,
        Document = 2,
    }

    #region Local Converters

    public class SearchPanelModeToIntConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return ((int) ((SearchPanelMode) value));
        }

        public object ConvertBack(object value, Type targetType, object parameter,
                                  System.Globalization.CultureInfo culture)
        {
            return (SearchPanelMode) Enum.ToObject(typeof (SearchPanelMode), ((int) value));
        }

        #endregion
    }

    public class NullToVisibilityConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value == null ? Visibility.Collapsed : Visibility.Visible;
        }

        public object ConvertBack(object value, Type targetType, object parameter,
                                  System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

    public class BoolToOppositeBoolConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter,
                              System.Globalization.CultureInfo culture)
        {
            return !(bool) value;
        }

        public object ConvertBack(object value, Type targetType, object parameter,
                                  System.Globalization.CultureInfo culture)
        {
            return !(bool) value;
        }

        #endregion
    }

    #endregion
}